#if defined (_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif

#ifndef JETBYTE_TOOLS_NODE_LIST_INCLUDED__
#define JETBYTE_TOOLS_NODE_LIST_INCLUDED__

///////////////////////////////////////////////////////////////////////////////

#include <wtypes.h>

///////////////////////////////////////////////////////////////////////////////
// Namespace: OldDreamTools
///////////////////////////////////////////////////////////////////////////////

namespace OldDreamTools {

///////////////////////////////////////////////////////////////////////////////
// CNodeList
///////////////////////////////////////////////////////////////////////////////

class CNodeList
{
   public :

      class Node
      {
         public :

            Node *Next() const;

            void Next(Node *pNext);

            void AddToList(CNodeList *pList);

            void RemoveFromList();

         protected :

            Node();
            ~Node();

         private :

            friend class CNodeList;

            void Unlink();

            Node *m_pNext;
            Node *m_pPrev;

            CNodeList *m_pList;
      };

      CNodeList();

      void PushNode(Node *pNode);

      Node *PopNode();

      Node *Head() const;

      size_t Count() const;

      bool Empty() const;

   private :

      friend void Node::RemoveFromList();

      void RemoveNode(Node *pNode);

      Node *m_pHead;

      size_t m_numNodes;
};

///////////////////////////////////////////////////////////////////////////////
// TNodeList
///////////////////////////////////////////////////////////////////////////////

template <class T> class TNodeList : public CNodeList
{
   public :

      T *PopNode();

      T *Head() const;

      static T *Next(const T *pNode);
};

template <class T>
T *TNodeList<T>::PopNode()
{
   return static_cast<T*>(CNodeList::PopNode());
}

template <class T>
T *TNodeList<T>::Head() const
{
   return static_cast<T*>(CNodeList::Head());
}

template <class T>
T *TNodeList<T>::Next(const T *pNode)
{
   return static_cast<T*>(pNode->Next());
}

///////////////////////////////////////////////////////////////////////////////
// Namespace: OldDreamTools
///////////////////////////////////////////////////////////////////////////////

} // End of namespace OldDreamTools

///////////////////////////////////////////////////////////////////////////////
// Lint options
//
//lint -restore
//
///////////////////////////////////////////////////////////////////////////////

#endif //JETBYTE_TOOLS_NODE_LIST_INCLUDED__

///////////////////////////////////////////////////////////////////////////////
// End of file
///////////////////////////////////////////////////////////////////////////////
